using System.Collections;
using System.Linq;
using System.Linq.Expressions;

namespace Magiq.Support {
    
    public class EnumerableSourceFinder {
        public IList FindSourceOf(IEnumerable items) {
            var queryable = items as IQueryable;
            if (queryable != null)
                return FindSourceFromQueryProvider(queryable);

            var list = items as IList;
            if (list != null) {
                if (list.IsFixedSize)
                    throw new SourceIsFixedSizeException(queryable);

                return list;
            }

            var parent = items.Field("source") as IList;

            if (parent == null)
                throw new SourceIsFixedSizeException(queryable);

            return FindSourceOf(parent);
        }

        private IList FindSourceFromQueryProvider(IQueryable queryable) {
            var constant = ConstantFrom(queryable.Expression);

            if (constant == null)
                throw new CannotResolveSourceException(queryable);

            var value = constant.Value.Field("enumerable") as IEnumerable;
            return FindSourceOf(value);
        }


        private static ConstantExpression ConstantFrom(Expression expression) {
            var constant = expression as ConstantExpression;

            if (constant != null)
                return constant;

            var call = expression as MethodCallExpression;

            return call == null ? null : ConstantFrom(call.Arguments[0]);
        }

    }
}